<!--
 * @Author: your name
 * @Date: 2021-01-26 15:25:14
 * @LastEditTime: 2021-06-15 10:26:04
 * @LastEditors: xuzp4
 * @Description: In User Settings Edit
 * @FilePath: \vue_demo\src\view\mountain\Demo.vue
-->
<template>
  <div>
    <div id="map"></div>
    <!-- <el-input v-model="queryVal" placeholder="输入车号"></el-input>
    <el-button type="primary">查询</el-button> -->
    <input id="queryVal" style="position: relative" />
    <button class="btn" @click="search">search</button>
  </div>
</template>

<script>
import { getFanceData, firstLorryData, secondLorryData, getLine } from "./data";
import lorryImage from "../../assets/dirty.png";
import excavator from "../../assets/my.png";
const mapboxgl = require("mapbox-gl");
var MapboxLanguage = require("@mapbox/mapbox-gl-language");
export default {
  name: "Demo",
  data() {
    return {
      // 围栏数据
      fanceData: {},
      // 机器位置数据
      lorryData: {},
      // 需要移动的机器集合
      movePints: [],
      // 点动画控制
      isMove: false,
      // 机器移动速度控制
      moveSpeed: 300,
      times: 0,
      mapAll: {},
    };
  },
  mounted() {
    // todo 执行顺序,响应判空,倾角控制
    // 加载地图
    this.initmap();
    // 查询围栏
    this.queryFance();
    // 查询点
    this.queryLorry();
    // 启动定时器
    this.queryLorryTimes();
  },

  methods: {
    // 查询跳转到目的机器
    search() {
      let queryParam = document.getElementById("queryVal").value;
      this.lorryData.body.map((item) => {
        if (item.name === queryParam) {
          this.mapAll.flyTo({
            center: [item.longitude, item.latitude],
            speed: 0.2,
          });
        }
      });
    },
    // 查询围栏
    queryFance() {
      this.fanceData = getFanceData();
    },
    // 查询点
    queryLorry() {
      this.lorryData = firstLorryData();
    },
    // 每隔10s查询新的点数据
    queryLorryTimes() {
      let i = 0;
      setInterval(() => {
        i++;
        const newLorryData = i % 2 ? secondLorryData() : firstLorryData();
        // 如果成功拿到响应，计算两次之间的距离，开启动画
        if (true) {
          // 计算
          this.movePints = this.computeDistance(
            newLorryData.body,
            this.lorryData.body
          );
          this.lorryData = newLorryData;
        }
      }, 10000);
    },
    // 计算两次响应之间每个点的距离
    computeDistance(newLorrys, oldLorrys) {
      let movePoints = [];
      newLorrys.map((newLorry) => {
        oldLorrys.map((oldLorry) => {
          if (newLorry.id === oldLorry.id) {
            const distanceX = newLorry.longitude - oldLorry.longitude;
            const distanceY = newLorry.latitude - oldLorry.latitude;
            const tempDis = {
              id: newLorry.id,
              x: distanceX / this.moveSpeed,
              y: distanceY / this.moveSpeed,
              startX: Number(oldLorry.longitude),
              startY: Number(oldLorry.latitude),
              endX: Number(newLorry.longitude),
              endY: Number(newLorry.latitude),
            };
            movePoints.push(tempDis);
          }
        });
      });
      this.isMove = true;
      this.times = 0;
      return movePoints;
    },
    initmap() {
      mapboxgl.accessToken =
        "pk.eyJ1Ijoiemh1MTIxMzgiLCJhIjoiY2trZG5zZ28yMDRqdzJ3bzU2eGQxNjU3cCJ9.mSwtLkCHXpcEIZZPxGoJog";
      var map = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/satellite-v9",
        zoom: 14,
        minZoom: 13,
        maxZoom: 19,
        center: [113.722, 24.552],
        pitch: 40,
        maxPitch: 50,
        // antialias: true
      });

      map.on("load", () => {
        // this.drawFence(map);
        // 添加图标
        map.loadImage(lorryImage, function (error, image) {
          // 宽体车
          if (error) throw error;
          map.addImage("lorry", image); // 给样式添加图像
        });
        map.loadImage(excavator, function (error, image) {
          if (error) throw error;
          map.addImage("excavator", image);
        });
        this.drawPoint(map);
        // this.drawDevice(map);
        // 绘制线
        this.drawLine(map);
        // 语言包
        map.addControl(
          new MapboxLanguage({
            defaultLanguage: "zh",
          })
        );
        // this.animateDevice(map);
      });

      // 缩放控制机械信息展示
      // this.zoom(map);
      this.mapAll = map;
    },
    // 围栏放在一个图层
    drawFence(map) {
      const source = this.fanceData.body.map((item) => {
        return {
          type: "Feature",
          properties: {
            color: item.fenceColor,
            name: item.fenceName,
          },
          geometry: {
            type: "Polygon",
            coordinates: [item.coordinateArrays],
          },
        };
      });
      map.addSource("fence", {
        type: "geojson",
        data: {
          type: "FeatureCollection",
          features: source,
        },
      });
      map.addLayer({
        id: "fence",
        source: "fence",
        type: "fill",
        layout: {},
        paint: {
          "fill-color": ["get", "color"],
          "fill-opacity": 0.2,
        },
      });
      map.on("mouseenter", "fence", function (e) {
        map.addLayer({
          id: "fenceName",
          type: "symbol",
          source: {
            type: "geojson",
            data: {
              type: "Feature",
              properties: {
                name: e.features[0].properties.name,
              },
              geometry: {
                type: "Polygon",
                coordinates: e.features[0].geometry.coordinates,
              },
            },
          },
          layout: {
            "text-field": ["get", "name"],
            "text-variable-anchor": ["top", "bottom", "left", "right"],
            "text-radial-offset": 0.5,
            "text-justify": "auto",
          },
          paint: {
            "text-color": "white",
          },
        });
      });
      map.on("mouseleave", "fence", function (e) {
        map.removeLayer("fenceName");
        map.removeSource("fenceName");
      });
    },
    // 绘制设备
    drawPoint(map) {
      for (let j = 0; j < this.lorryData.body.length; j++) {
        const singleLorry = this.lorryData.body[j];
        // 添加数据源
        map.addSource("point" + singleLorry.id, {
          type: "geojson",
          data: {
            type: "Point",
            coordinates: [singleLorry.longitude, singleLorry.latitude],
          },
        });
        // 缩小时显示点
        map.addLayer({
          id: "point" + singleLorry.id,
          source: "point" + singleLorry.id,
          type: "circle",
          layout: {
            visibility: "visible",
          },
          paint: {
            "circle-radius": 3,
            "circle-color":
              singleLorry.type === "minecard" ? "#e44f3c" : "yellow",
          },
        });
        // 放大时显示图标
        map.addLayer({
          id: "pointIcon" + singleLorry.id,
          source: "point" + singleLorry.id,
          type: "symbol",
          layout: {
            visibility: "none",
            "icon-image":
              singleLorry.type === "minecard" ? "lorry" : "excavator",
            "icon-allow-overlap": true,
            // "icon-size": 0.13
            "icon-size": singleLorry.type === "minecard" ? 0.13 : 0.2,
          },
          paint: {},
        });
        // 放大时显示文字描述
        map.addLayer({
          id: "pointSymbol" + singleLorry.id,
          type: "symbol",
          source: "point" + singleLorry.id,
          layout: {
            "symbol-avoid-edges": true,
            visibility: "none",
            "text-field": `${singleLorry.name}(${singleLorry.loadCount}车)`,
            "text-anchor": "bottom",
            "text-offset": [0, -1],
            "text-allow-overlap": true,
            "text-ignore-placement": true,
            "text-size": 13,
          },
          paint: {
            "text-color": "white",
            "text-halo-color": "#DAA520",
            "text-halo-width": 1,
          },
        });
      }
    },
    drawDevice(map) {
      const mineSource = this.lorryData.body.map((singleLorry) => {
          return {
            type: "Feature",
            geometry: {
              type: "Point",
              coordinates: [singleLorry.longitude, singleLorry.latitude],
            },
          };
      });
      map.addSource("device", {
        type: "geojson",
        data: {
          type: "FeatureCollection",
          features: mineSource,
        },
      });
      map.addLayer("device", {
        id: "device",
        source: "device",
        type: "circle",
        layout: {
          visibility: "visible",
        },
        paint: {
          "circle-radius": 3,
          "circle-color":"#e44f3c",
        },
      });
    },
    // 实时移动
    animateDevice(map) {
      // 点动画
      const pointOnCircle = (id) => {
        for (let i = 0; i < this.movePints.length; i++) {
          let item = this.movePints[i];
          if (id === item.id) {
            let disX = this.movePints[i].startX;
            let disY = this.movePints[i].startY;
            if (this.times <= this.moveSpeed) {
              disX = this.movePints[i].startX + item.x * this.times;
              disY = this.movePints[i].startY + item.y * this.times;
            }
            return {
              type: "Point",
              coordinates: [disX, disY],
            };
          }
        }
      };

      setInterval(() => {
        if (this.isMove) {
          this.times++;
          this.movePints.map((item) => {
            if (this.times <= this.moveSpeed) {
              map.getSource("point" + item.id).setData(pointOnCircle(item.id));
            }
          });
        }
      }, 10000 / this.moveSpeed);
    },
    // 绘制线
    drawLine(map) {
      map.addLayer({
        id: "line-animation",
        type: "line",
        source: {
          type: "geojson",
          data: getLine(),
        },
        layout: {
          "line-cap": "round",
          "line-join": "round",
        },
        paint: {
          "line-color": "red",
          "line-width": 2,
          "line-opacity": 0.8,
        },
      });
    },
    // 缩放
    zoom(map) {
      map.on("zoom", () => {
        for (let j = 0; j < this.lorryData.body.length; j++) {
          const singleLorry = this.lorryData.body[j];
          let showType = false;
          if (map.getZoom() > 15) {
            showType = true;
          } else {
            showType = false;
          }
          map.setLayoutProperty(
            "pointSymbol" + singleLorry.id,
            "visibility",
            showType ? "visible" : "none"
          );
          map.setLayoutProperty(
            "point" + singleLorry.id,
            "visibility",
            showType ? "none" : "visible"
          );
          map.setLayoutProperty(
            "pointIcon" + singleLorry.id,
            "visibility",
            showType ? "visible" : "none"
          );
        }
      });
    },
  },
};
</script>

<style scoped>
#map {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
}
.btn {
  position: relative;
  width: 90px;
  height: 20px;
}
</style>
